Search on specific Liferay private page - liferay

For search i use liferay-ui:search in the dockbar. User should be able to define search scope (specific private page) by choosing it from dropdown list.
How can i implement search on specific private page?
And 1 more question. Seems it's a bug, but user is able to search only while he is on specific private page. If he move to another page - search button is "disabled" - nothing happens when he clic it. For admin account everything works fine - i am able to search being on any page.
Thanks!

OK. 1st step was to place hook on [b]html/taglib/search/start.jsp[/b]. I passed an extra id parameter to define on which private page i gonna search.
<input name="<%= namespace %>keywords" size="30" title="<liferay-ui:message key="search" />" type="text" value="<%= HtmlUtil.escapeAttribute(keywords) %>" />
<input name="<%= namespace %>groupid" value="0" type="hidden" />
<select name="<%= namespace %>scopeId" title="<liferay-ui:message key="scope" /> ">
<option value="0" <%= selected == 0 ? "selected" : ""%>><liferay-ui:message key="everything" /></option>
<option value="1" <%= selected == 1 ? "selected" : ""%>>Новости</option>
<option value="2" <%= selected == 2 ? "selected" : ""%>>Сотрудники</option>
<option value="3" <%= selected == 3 ? "selected" : ""%>>Новому сотруднику</option>
<option value="4" <%= selected == 4 ? "selected" : ""%>>Корпоративные правила</option>
<option value="5" <%= selected == 5 ? "selected" : ""%>>Продукты</option>
<option value="6" <%= selected == 6 ? "selected" : ""%>>Wiki</option>
<option value="7" <%= selected == 7 ? "selected" : ""%>>События</option>
<option value="8" <%= selected == 8 ? "selected" : ""%>>Форум</option>
</select>
2nd step was to hook on [b]html/portlet/search/main_search.jsp[/b]. There i was going to filter [b]ALL[/b] search results and display only those which needed by request from [b]select field[/b]. It's OK for non instanceble custom portlets with have different id, i just filter by portletId and display result.
Hits hits = indexer.search(searchContext);
List<Document> documents = new ArrayList<Document>();
documents = hits.toList();
...
if (documents.size() != 0) {
List<Document> toDelete = new ArrayList<Document>();
for (Document document : documents) {
String id = document.getPortletId();
id = document.get(Field.PORTLET_ID);
switch (scopeId) {
case 0:
break;
case 1:
if (!id.equals(NEWS_PORTLET_ID)) {
toDelete.add(document);
}
break;
....
if (toDelete.size() != 0) {
documents.removeAll(toDelete);
hits.setDocs(documents.toArray(new Document[documents.size()]));
if (documents.size() == 0) {
hits.setLength(0);
}
}
All fine. But 3 of my pages all have asset publisher portlet (portletId = 15), so if i filter by portlet id - i will get results from all 3 pages. Maybe i can get instance id of portlet which document belongs to. Or maybe there is some other way to do search.
Atm i try to implement my CustomJournalArticleIndexer. The idea is Indexer adds field containing portlet's instance id. So later in main_search.jsp i can do something like document.getPortletInstanceId and compare it with a constant paired with scopeId of my request.
Any suggestions here?
Thanks and... from Russia with love!

Related

simplesearch modx with date dropdown integration

Iam new to modx(revolution version 2.5.7) and simple search(simplesearch-1.9.2-pl)
I need to add date dropdown (need to fetch results with matching date which is a template variable as type date ) with simplesearch extra in modx plugin. I have attached screenshot of my searchpage for reference. Please help me to solve this.
https://forums.modx.com/thread/95128/advsearch-to-show-search-value-based-on-dropdown-box.
After many painful debugging , got my code working.
[b]My code[/b] ,
[[!AdvSearchForm? &tpl=`AdvanceSearchForm_tpl`]]
</h1>
<h2>Results</h2>
<p>[[!AdvSearch? &parents=`12`&queryHook=`FilterCalenderSnippet` ]]
[b]form tpl (AdvanceSearchForm_tpl) :--[/b]
[code]<form id="[[+advsearch.asId]]_advsea-form" class="advsea-form" action="[[~[[+advsearch.landing]]]]" method="[[+advsearch.method]]">
<fieldset>
<input type="hidden" name="id" value="[[+advsearch.landing]]" />
<input type="hidden" name="asId" value="[[+advsearch.asId]]" />
[[+advsearch.helpLink]]<input type="text" id="[[+advsearch.asId]]_advsea-search" name="[[+advsearch.searchIndex]]" value="[[+advsearch.searchValue]]" />
[[$SeminarCalendarDateChunk]]// give the dropdown of dates,you can put your form elements
[[+advsearch.liveSearch:isnot=`1`:then=`<input type="submit" id="[[+advsearch.asId]]_advsea-submit" name="sub" value="[[%advsearch.search? &namespace=`advsearch` &topic=`default`]]" />`:else`=``]]
</fieldset>
</form>
[[+advsearch.resultsWindow]]
[b]Query Hook snippet(FilterCalenderSnippet)[/b]
[ul]
[li]My Date tv is EventDateTv[/li]
[/ul]
[code]
<?php
$andConditions = array();
// here i need to show events between one given input month. so I did some php to fetch first and last days of given month
if (!empty($_REQUEST['calendar_date'])) {
$dateToTest = $_REQUEST['calendar_date'];// my form element name is calendar_date
$lastday = date('Y-m-t',strtotime($dateToTest));
$andConditions['tv.EventDateTv:>='] = $dateToTest;
$andConditions['tv.EventDateTv:<='] = $lastday ;
}
if (!empty($andConditions)) {
$qhDeclaration = array(
'qhVersion' => '1.3',
'andConditions' => $andConditions
);
$hook->setQueryHook($qhDeclaration);
}
return true;
[/code]`enter code here`

MVC 5 / Bind dropdownlist including disabled values

(My first quesion, I'm quite impressed :) )
First, please excuse my English, I'm French ;)
My issue is about DropDownList which is linked(bind) to a required field (F, int) of an object O (edited in a view V) and contains a list of elements (LE), some of them disabled.
The behavior I want in the view :
when I create an object, the validation must trigg if nothing
is selected in the list (OK)
when I create an object, the disabled elements of the list must not be selectable (OK)
when I edit an object, if the field is among enabled values, same behavior (OK)
when I edit an object, if the field is among disabled values, it must be displayed and selected when viewed (OK)
when I edit an object, if the field is among disabled values, when I post data, the client validation must authorize disabled values to be validated (OK with a little javascript)
My issue :
when I edit an object, if the field is among disabled values, when I
post data, the model contains null for the field linked to the
dropdownlist even if I include an hidden field with the Id.
Here is some of my code to help understand my issue.
Any idea of how I could include disabled values of my dropdown list in the model when I post data ?
Thanks for any help !
View :
<div class="col-md-3">
#Html.DropDownListFor(model => model.Currency.Id, (SelectList)ViewBag.Currencies, new { #class = "form-control ignore-desactivated" })
#Html.ValidationMessageFor(model => model.Currency, "", new { #class = "text-danger" })
</div>
JS :
$(function () {
$('form').validate().settings.ignore = '.ignore-desactivated';
});
Source when edition :
<div class="col-md-3">
<select class="form-control ignore-desactivated" data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="Currency_Id" name="Currency.Id">
<option value="-1"></option>
<option disabled="disabled" value="9">Angolan kwanza (desactivated)</option>
<option value="10">Argentine peso</option>
<option disabled="disabled" selected="selected" value="1">Euro (desactivated)</option>
<option disabled="disabled" value="56">Gibraltar pound (desactivated)</option>
<option value="3">Great Britain Pound</option>
</select>
<span class="field-validation-valid text-danger" data-valmsg-for="Currency" data-valmsg-[replace][1]="true"></span>
</div>
My model when I want to save data :
https://i.stack.imgur.com/jQ9aH.png
... and I found an answer a few minutes after asking it (thanks to my colleagues)...
I don't know if that's correct, but a little js code to remove disabled items before the post did the trick :
//Delete disabled elements of lists before submit
$('form').submit(function () {
$('.ignore-desactivated').each(function () {
$(this).children().each(function () {
$(this).removeAttr('disabled');
});
})
})

Getting Flask to alter selected value in HTML drop down

I'm writing a prototype front end for a home heating control system and when the user selects the room and day of the week from the drop down box, I want to be able to query the Redis database and retrieve the currently set temperatures for each hour and use this to set the selected value in the temperature drop down boxes. The user can then change a value or values and submit them. I have the submit and write working, just trying to get my head around setting the selected.
Here's the HTML:
{% extends "bootstrap/base.html" %}
{% block title %}Setting Room Temperatures{% endblock %}
{% block navbar %}
<div class="navbar navbar-fixed-top">
<!-- ... -->
</div>
{% endblock %}
{% block content %}
</head>
<body>
<h1>Room temperature configuration</h1>
<form action="{{ url_for('heating_config_form')}}" method="post" class="form-inline">
<div class="form-group">
<label for="roomselect">Room:</label>
<select class="form-control" name="roomselect">
<option value="dining">Dining</option>
<option value="kitchen">Kitchen</option>
<option value="lounge">Lounge</option>
<option value="study">Study</option>
</select>
</div>
<br>
<br>
<div class="form-group">
<label for="dayselect">Day :</label>
<select class="form-control" name="dayselect">
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
</div>
<br>
<br>
<div class="form-group">
<label for="1AM">1AM :</label>
<select class="form-control" name="1AM">
<option value="5">5</option>
<option value="6">6</option>
</select>
<label for="2AM">2AM :</label>
<select class="form-control" name="2AM">
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
<br>
<br>
<button type="submit" value="submitted" name="update">Update temperature </button><br>
<br>
</form>
<br>
</body></html>
{% endblock %}<html><head>
And here's the Python Flask code
from flask import Flask
from flask import request
from flask import render_template
from flask_bootstrap import Bootstrap
import redis
app = Flask(__name__)
app.debug = True
bootstrap = Bootstrap(app)
db = redis.Redis('localhost')
#app.route('/', methods=['GET','POST'])
def heating_config_form():
error=""
if request.method == 'POST' and request.form['update'] == 'submitted':
Room = (request.form.get('roomselect'))
Day = (request.form.get('dayselect'))
AM1 = (request.form.get('1AM'))
AM2 = (request.form.get('2AM'))
key = (Room + "_" + Day)
db.hset(key, "1:00", AM1)
db.hset(key, "2:00", AM2)
return render_template('set-room-tempv5.html')
else :
return render_template('set-room-tempv5.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
I'm aware there are probably better ways of approaching this (WTForms?) but wanted to get a simple setting interface that I understand so I can prototype the system while developing a better front end, as I'm new to Flask and don't want the whole heating system to be dependent on my ability to pick this up :)
Adding the temperature to the database works fine, this is a typical monitor output from the redis-cli monitor
127.0.0.1:6379> monitor
OK
1482336847.287342 [0 127.0.0.1:34180] "HSET" "kitchen_tuesday" "1:00" "5"
1482336847.288042 [0 127.0.0.1:34180] "HSET" "kitchen_tuesday" "2:00" "5"
I was thinking that maybe something like the following context processor could help?
#app.context_processor
def utility_processor():
def retrieve_temp(sroom, sday, stime):
skey= (sroom + "_" + sday)
stemp = db.hget(skey, stime)
return stemp
return dict(retrieve_temp=retrieve_temp)
which would make the function retrieve_temp available to all templates - I think!
Then somehow, once the template is rendered, the default room and day is used to set the "selected" option on the time drop downs, and then every time the room and day drop downs are moved, the same happens again.
So if the default is dining and Monday given they are the first in the select options, the temperatures for 1AM and 2AM are retrieved and set as selected for these drop downs (there are more times and more temps, these have been deleted for brevity). If the room and/or the day is changed, it happens again.
OK - So just wanted to be sure on your question before I gave you information to solve the problem. The approach you've outline as an alternative in the comments is the easiest way to get this to work (e.g. intermediary page to make the first selection).
It's important to remember that any python or jinja2 code is only going to executed 1 time. Jinja2 uses some logic to render the HTML output and then Flask responds with a static HTML page to the browser, so you can use a context_processor to pass specific logic to jinja2, but once Flask renders the page any interactivity would need to be managed by javascript.
It looks like you are using Bootstrap, which includes jQuery javascript library. jQuery is great (in my opinion) because it handles some browser quirks for you in terms of how it interacts with and manipulates the DOM (e.g. the Document Object Model, javascript's representation of your HTML elements).
So, if you want to dynamically populate the second select you can design some code to asynchronously (e.g. without making another HTTP request or "reloading" the page) send data from the browser to a Flask endpoint to fetch the required options then update the front end. I'll give you an example:
HTML looks like this (I'm just adding ID's. The for tag is suppose to reference the ID field, not the name, and it also makes the javascript selection easier):
<div class="form-group">
<label for="roomselect">Room:</label>
<select class="form-control" name="roomselect" id="roomselect">
<option value="dining">Dining</option>
<option value="kitchen">Kitchen</option>
<option value="lounge">Lounge</option>
<option value="study">Study</option>
</select>
</div>
<div class="form-group">
<label for="dayselect">Day:</label>
<select class="form-control" name="dayselect" id="dayselect">
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
</div>
<div class="form-group">
<label for="1AM">1AM:</label>
<select class="form-control" name="1AM" id="1AM">
<option value="5">5</option>
<option value="6">6</option>
</select>
<label for="2AM">2AM:</label>
<select class="form-control" name="2AM" id="2AM" disabled>
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
Then, you need to add a javascript event listener and AJAX method, usually you do this in the bottom of the body of your HTML or in a linked file:
<script charset="utf-8" type="text/javascript">
// this is called a javascript closure. it also wont run the code until the page is finished loading
// and it protects the scope of your variables from other code you may later add to the page
$(function() {
var select_room = $('#roomselect'),
select_day = $('#dayselect'),
select_1am = $('#1am'),
select_2am = $('#2am');
select_room.on('change', function() {
// fires when room selection changes
getUpdatedSettings();
});
select_day.on('change', function() {
// fires when day selection changes
getUpdatedSettings();
});
function getUpdatedSettings() {
// data to send back to the server
var send = {
room: select_room.val(),
day: select_day.val()
};
// make the selections disabled while fetching new data
select_1am.attr('disabled', true);
select_2am.attr('disabled', true);
$.getJSON("/_get_updated_settings", send, function(response) {
// this send the room and the day select vals to the URL specified
// we will need to add a handler for this in Flask
// for the purpose of the example I am assuming the response will be
// a JSON object that has a dictionary of elements ("am_1" and "am_2")
// each of which is a list of values for the selects....
console.log(response); // good for QA!
// populate 1am
select_1am.empty();
$.each(response.am_1, function (index, value) {
select_1am.append(
$('<option>', {
value: value,
text: value
}, '</option>'))
});
// populate 2am
select_2am.empty();
$.each(response.am_2, function (index, value) {
select_2am.append(
$('<option>', {
value: value,
text: value
}, '</option>'))
});
// remove disabled now
select_1am.removeAttr('disabled');
select_2am.removeAttr('disabled');
});
}
});
</script>
Now, you need to add some Flask logic to handle this AJAX request:
from flask import jsonify
#app.route('/_get_updated_settings')
def get_updated_settings():
# good for debug, make sure args were sent
print request.args
day = request.args.get('day', 'default_if_none')
room = request.args.get('room', 'default_if_none')
key = (room + "_" + day)
output = {}
# I have no idea what this returns...just doing a list generator here assuming we get a list of values
output['am_1'] = [x for x in db.hget(skey, '1am')]
output['am_2'] = [x for x in db.hget(skey, '1am')]
return jsonify(output)
Ha...turned out a bit longer than I expected, but this should at the very least provide you with a straw man to get functionality like this working. Javascript definitely provides for a better user experience, but you can generally accomplish the same thing by having a series of intermediary forms that populate static pages.

Populate Select using ViewBag without using html Helper

I Have this in my controller
ViewBag.list = new SelectList(db.ListOfDB, "Value", "Text");
I need to create a Select, but without using the #Html.DropDownList I try to use this:
<select id="mylist"> ??? (selectitem) #ViewBag.list ??? </select>
How create select based from Viewbag, but not use Html.Helper
You can pass your list to the view on your model. You could then do
<select id="myList">
#foreach(var item in Model.myList)
{
<option value="#item.Value">item.Name</option>
}
</select>
#{
ViewBag.Title = "";
Layout = "~/Views/Shared/_LayoutLanding.cshtml";
List<SelectListItem> list = ViewBag.list;
}
#for(int i = 0; i < list.Count; i++)
{
<option value="#list[i].Value">#list[i].Text</option>
}
After many attempts, this one worked for me
This one in the Controller -
ViewBag.ilist = new SelectList(db.tblPersons.Where(d => d.PersonTyp == "SUPPLIER").ToList(), "slno", "PersonName");
'slno' being the Id column and 'PersonName' being the 'Data' column
Then in Razor page (Without HTML helpers)
<select id="dpdnperson" name="dpdnperson" class="dropdown btn bg-gradient-primary" style="color:white; width:100%" Font-Size="Medium">
<option>-- SELECT --</option>
#foreach (var item in ViewBag.ilist)
{
<option value="#item.Value" >#item.Text</option>
}
</select>

How can I hide whmcs buttons?

Hi I hope someone can help on the client details page I need to hide the Email forwarding button and the DNS management button if the client has selected custom nameservers. I just can't work it out son any help is much welcomed ..Here is the code that takes the input;
<form method="post" action="{$smarty.server.PHP_SELF}?action=domaindetails">
<input type="hidden" name="sub" value="savens">
<input type="hidden" name="id" value="{$domainid}">
<p><input type="radio" name="nschoice" value="default" id="nschoicedefault" onclick="usedefaultns()"{if $defaultns} checked{/if} /> <label for="nschoicedefault">{$LANG.nschoicedefault}</label><br />
<input type="radio" name="nschoice" value="custom" id="nschoicecustom" onclick="usecustomns()"{if !$defaultns} checked{/if} /> <label for="nschoicecustom">{$LANG.nschoicecustom}</label></p>
And here is the code for the buttons;
{if $emailforwarding}
<td><form method="post" action="{$smarty.server.PHP_SELF}?action=domainemailforwarding">
<input type="hidden" name="domainid" value="{$domainid}">
<p align="center">
<input type="submit" value="{$LANG.domainemailforwarding}" class="button">}
</p>
</form></td>
{/if}
{if $dnsmanagement}
<td><form method="post" action="{$smarty.server.PHP_SELF}?action=domaindns">
<input type="hidden" name="domainid" value="{$domainid}">
<p align="center">
{<input type="submit" value="{$LANG.domaindnsmanagement}" class="button">}
</p>
</form></td>
{/if}
I suggest writing a helper function and calling it at the top of the tpl file
and passing the domain id to it.
You can then use the WHMCS internal API function Domain Nameservers to get the domains nameservers then compare them against the default nameservers in the tblconfiguration in the WHMCS database.
Something like this
{php}
// include our helper php file
require_once(dirname(__FILE__).'/Helper.php');
//get domain id from our template variables
$domainid = $this->get_template_vars('domainid');
//call to our helper function passing the domain ID
$hasCustomeNameServers = Helper::hasCustomNameServers($domainid);
//Once we've compared the nameservers agains the default ones we write
//our binary check to the template
if($hasCustomeNameServers >0){
$this->assign('hasCustomeNameServers',true);}
{/php}
Then in side our Helper.php we have something like the following
<?php
class Helper {
public static function hasCustomNameServers($domainid) {
$isCustom = 0;
//Interal API call to get the domains nameservers
$command = "domaingetnameservers";
$adminuser = "admin";
$values["domainid"] = $domainid;
$results = localAPI($command,$values,$adminuser);
//get default nameservers
$defautName1 ='';
$sql = mysql_query('SELECT value FROM tblconfiguration '.
' WHERE setting = "DefaultNameserver1"');
if ($res = mysql_fetch_assoc($sql)) {
$defautName1 = $res["value"];}
$defautName2 ='';
$sql = mysql_query('SELECT value FROM tblconfiguration '.
' WHERE setting = "DefaultNameserver2"');
if ($res = mysql_fetch_assoc($sql)) {
$defautName2 = $res["value"];}
//compare results
foreach ($results as &$value) {
if($value == $defautName1 || $value == $defautName2){
$isCustom++;
}
}
return $isCustom;
}
}
Now it's simply a matter on the template to wrap the {if $emailforwarding} and the {if $dnsmanagement} blocks around our check {if !hasCustomeNameServers}
I hope this helps you in the right direction this is by no means a comprehensive answer but is a guide towards the approach I think you should take in implementing your solution.

Resources